1812 2020-01-17 2024-10-15

Bean大家应该都了解,鉴于前面的文章介绍的细节过于纵向,因此我们单独开一篇文章介绍Spring Bean的全生命周期。从横向的视角,来看看在Bean初始化、填充属性、实例化的各个环节,我们都可以做哪些事情。

一、一个类

理论前面已经讲得够多了,这次我们直接上测试代码,如下

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

import java.lang.reflect.Constructor;

// 一个类,解决你关于Spring bean生命周期的全部疑惑!
public class BeanLifeCycleTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanLifeCycleTest.class);
        context.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class));
        context.getBean("testBean");
    }

    @Bean
    public SmartInstantiationAwareBeanPostProcessorCls smartInstantiationAwareBeanPostProcessorCls() {
        return new SmartInstantiationAwareBeanPostProcessorCls();
    }
    @Bean
    public InstantiationAwareBeanPostProcessorCls instantiationAwareBeanPostProcessorCls() {
        return new InstantiationAwareBeanPostProcessorCls();
    }
    @Bean
    public MergedBeanDefinitionPostProcessorCls mergedBeanDefinitionPostProcessorCls() {
        return new MergedBeanDefinitionPostProcessorCls();
    }
    @Bean
    public BeanPostProcessorCls beanPostProcessorCls() {
        return new BeanPostProcessorCls();
    }
    @Bean
    public DestructionAwareBeanPostProcessorCls destructionAwareBeanPostProcessorCls() {
        return new DestructionAwareBeanPostProcessorCls();
    }

    private static class TestBean implements InitializingBean, DisposableBean {
        @Autowired
        private Animal animal;

        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("get a animal: " + animal.name);
            System.out.println("8. InitializingBean.afterPropertiesSet:已经激活Aware接口且bean所有属性已设置完毕");
        }

        @Override
        public void destroy() throws Exception {
            System.out.println("F2:DisposableBean.destroy:销毁bean");
        }

        @Override
        public String toString() {
            return "animal name is " + (animal == null ? null : animal.name);
        }
    }

    @Bean
    public Animal panda() {
        return new Animal("国宝熊猫");
    }

    private static class Animal {
        String name = "no name";
        public Animal(String name) {
            System.out.println("3. Animal init:" + name);
            this.name = name;
        }
        @Override
        public String toString() {
            return "animal name is " + name;
        }
    }

    private static class SmartInstantiationAwareBeanPostProcessorCls implements SmartInstantiationAwareBeanPostProcessor {
        @Override
        public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
            // 这个接口主要是spring框架内部来使用
            // 用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)
            System.out.println("1. SmartInstantiationAwareBeanPostProcessor.predictBeanType:预测Bean类型: " + beanName + ", " + beanClass);
            return null;
        }

        @Override
        public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
            // 这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器)
            System.out.println("3. SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors:确定候选构造器: "+ beanName + ", " + beanClass);
            return null;
        }

        @Override
        public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
            // 获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)
            System.out.println("C3");
            return null;
        }
    }

    private static class InstantiationAwareBeanPostProcessorCls implements InstantiationAwareBeanPostProcessor {
        // 实例化前后的后处理
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            // 这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;
            System.out.println("2. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation:实例化之前: " + beanName + ", " + beanClass);
            return null;
        }

        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            // 在对象实例化完毕,执行populateBean之前,如果返回false则spring不再对对应的bean实例进行自动依赖注入。
            System.out.println("5. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation:实例化完成之后: " + beanName + ", " + bean);
            return true;
        }

        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            // 这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中
            // @Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。
            System.out.println("6. InstantiationAwareBeanPostProcessor.postProcessProperties:开始注入/填充属性: " + beanName + ", " + bean + ", " + pvs);
            return pvs;
        }
    }

    private static class MergedBeanDefinitionPostProcessorCls implements MergedBeanDefinitionPostProcessor {
        @Override
        public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
            // 在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用
            // 这个算是将merged BeanDefinition暴露出来的一个回调
            System.out.println("4. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition:处理MergedBeanDefinition: " + beanName + ", " + beanType + ", " + beanDefinition);
        }
    }

    private static class BeanPostProcessorCls implements BeanPostProcessor {
        // 初始化前后的后处理
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            // 该方法在bean实例化完毕(且已经注入完毕),在afterPropertiesSet或自定义init方法执行之前
            System.out.println("7. BeanPostProcessor.postProcessBeforeInitialization:BeanPostProcessor:实例化完成,初始化开始: " + beanName + ", " + bean);
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            // 在afterPropertiesSet或自定义init方法执行之后
            System.out.println("8. BeanPostProcessor.postProcessAfterInitialization:初始化结束");
            return bean;
        }
    }

    private static class DestructionAwareBeanPostProcessorCls implements DestructionAwareBeanPostProcessor {
        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            // 这里实现销毁对象的逻辑
            System.out.println("9. DestructionAwareBeanPostProcessor.postProcessBeforeDestruction: " + beanName + ", " + bean);
        }

        @Override
        public boolean requiresDestruction(Object bean) {
            // 判断是否需要处理这个对象的销毁
            System.out.println("9. DestructionAwareBeanPostProcessor.requiresDestruction: " + bean);
            return true;
        }
    }
}

二、日志输出

1、Spring初始化日志

22:25:55.634 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4fccd51b
22:25:55.662 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
22:25:55.784 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
22:25:55.788 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
22:25:55.790 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
22:25:55.793 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
22:25:55.800 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanPostProcessorCls'
22:25:55.802 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanLifeCycleTest'
22:25:55.810 [main] INFO org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'beanLifeCycleTest' of type [site.xiaokui.db.spring.BeanLifeCycleTest] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
22:25:55.813 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instantiationAwareBeanPostProcessorCls'
22:25:55.814 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'smartInstantiationAwareBeanPostProcessorCls'
22:25:55.816 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mergedBeanDefinitionPostProcessorCls'
22:25:55.816 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'destructionAwareBeanPostProcessorCls'

2、自定义输出

# 初始化 Animal
1. SmartInstantiationAwareBeanPostProcessor.predictBeanType:预测Bean类型: panda, class site.xiaokui.db.spring.BeanLifeCycleTest$Animal
1. SmartInstantiationAwareBeanPostProcessor.predictBeanType:预测Bean类型: panda, class site.xiaokui.db.spring.BeanLifeCycleTest$Animal
22:25:55.823 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'panda'
2. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation:实例化之前: panda, class site.xiaokui.db.spring.BeanLifeCycleTest$Animal
3. Animal init:国宝熊猫
4. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition:处理MergedBeanDefinition: panda, class site.xiaokui.db.spring.BeanLifeCycleTest$Animal, Root bean: class [null]; scope=singleton; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=beanLifeCycleTest; factoryMethodName=panda; initMethodName=null; destroyMethodName=(inferred); defined in site.xiaokui.db.spring.BeanLifeCycleTest
5. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation:实例化完成之后: panda, animal name is 国宝熊猫
6. InstantiationAwareBeanPostProcessor.postProcessProperties:开始注入/填充属性: panda, animal name is 国宝熊猫, PropertyValues: length=0
7. BeanPostProcessor.postProcessBeforeInitialization:BeanPostProcessor:实例化完成,初始化开始: panda, animal name is 国宝熊猫
8. BeanPostProcessor.postProcessAfterInitialization:初始化结束
9. DestructionAwareBeanPostProcessor.requiresDestruction: animal name is 国宝熊猫
9. DestructionAwareBeanPostProcessor.requiresDestruction: animal name is 国宝熊猫
22:25:55.904 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'testBean'

# 初始化 TestBean
2. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation:实例化之前: testBean, class site.xiaokui.db.spring.BeanLifeCycleTest$TestBean
3. SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors:确定候选构造器: testBean, class site.xiaokui.db.spring.BeanLifeCycleTest$TestBean
4. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition:处理MergedBeanDefinition: testBean, class site.xiaokui.db.spring.BeanLifeCycleTest$TestBean, Root bean: class [site.xiaokui.db.spring.BeanLifeCycleTest$TestBean]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
5. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation:实例化完成之后: testBean, animal name is null
6. InstantiationAwareBeanPostProcessor.postProcessProperties:开始注入/填充属性: testBean, animal name is null, PropertyValues: length=0
1. SmartInstantiationAwareBeanPostProcessor.predictBeanType:预测Bean类型: testBean, class site.xiaokui.db.spring.BeanLifeCycleTest$TestBean
1. SmartInstantiationAwareBeanPostProcessor.predictBeanType:预测Bean类型: testBean, class site.xiaokui.db.spring.BeanLifeCycleTest$TestBean
7. BeanPostProcessor.postProcessBeforeInitialization:BeanPostProcessor:实例化完成,初始化开始: testBean, animal name is 国宝熊猫
get a animal: 国宝熊猫
8. InitializingBean.afterPropertiesSet:已经激活Aware接口且bean所有属性已设置完毕
8. BeanPostProcessor.postProcessAfterInitialization:初始化结束
9. DestructionAwareBeanPostProcessor.requiresDestruction: animal name is 国宝熊猫

三、总结

纸上得来终觉浅,绝知此事须躬行。花点时间,跟下代码和日志,你也会有自己的理解。

下篇我们将详细分析Spring MVC与Servlet标准的整合,以及WebApplicationContext在Spring的应用。

总访问次数: 40次, 一般般帅 创建于 2020-01-17, 最后更新于 2024-10-15

进大厂! 欢迎关注微信公众号,第一时间掌握最新动态!